﻿Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text
Imports System.Web
Imports System.Web.Security
Imports FY.YinXinSDK.Mass
Imports FY.YinXinSDK.RecMsg
Imports FY.YinXinSDK.ReplyMsg
Imports FY.YinXinSDK.CustomerService
Imports FY.YinXinSDK.Menu
Public Delegate Function MyFunc(Of T1, T2, TResult)(t As T1, p As T2) As TResult
Public Delegate Sub SetAccessTokenHandler(credential As ClientCredential)
Public Delegate Function GetAccessTokenHandler() As String
Public Class YinXin

    '接收到多平台消息时的委托事件
    Public Delegate Sub ReceivePlatMsg(platcode As String, msgXmlStr As String, msgDict As Dictionary(Of String, String))
    'appid和appsecret字典
    Friend Shared DicAppID As Dictionary(Of String, String) = New Dictionary(Of String, String)()
    Friend Shared DicAppSecret As Dictionary(Of String, String) = New Dictionary(Of String, String)()
    '公众平台token信息
    Friend Shared DicToken As Dictionary(Of String, String) = New Dictionary(Of String, String)()
    '加锁标记
    Private Shared lockObj As Object = New Object()
    'AccessToken缓存字典
    Private Shared DicM_setHandler As Dictionary(Of String, SetAccessTokenHandler) = New Dictionary(Of String, SetAccessTokenHandler)()
    Private Shared DicM_getHandler As Dictionary(Of String, GetAccessTokenHandler) = New Dictionary(Of String, GetAccessTokenHandler)()
    '事件处理缓存字典
    Private Shared m_msgHandlers As Dictionary(Of String, Object) = New Dictionary(Of String, Object)()
    '定义一个委托类型的事件，当接收到消息时抛出此事件
    Public Shared Event OnReceivePlatMsgEvent As ReceivePlatMsg
    'token信息相关
    Public Shared Function getTokenState(platcode As String) As Boolean
        Return DicToken.ContainsKey(platcode)
    End Function
    Public Shared Sub SetToken(platcode As String, tokenstr As String)
        DicToken(platcode) = tokenstr
    End Sub
    Public Shared Function GetToken(platcode As String) As String
        Return DicToken(platcode)
    End Function
    '添加平台相关信息
    Public Shared Sub ConfigGlobalCredential(platcode As String, CurAppId As String, CurAppSecret As String)
        SyncLock lockObj
            DicAppID(platcode) = CurAppId
            DicAppSecret(platcode) = CurAppSecret
        End SyncLock
    End Sub
    Public Shared Function GetAppID(platcode As String) As String
        Dim result As String
        If DicAppID.ContainsKey(platcode) Then
            result = DicAppID(platcode)
        Else
            result = ""
        End If
        Return result
    End Function
    Public Shared Function GetAppSecret(platcode As String) As String
        Dim result As String
        If DicAppSecret.ContainsKey(platcode) Then
            result = DicAppSecret(platcode)
        Else
            result = ""
        End If
        Return result
    End Function
    '配置access_token缓存
    Public Shared Sub ConfigAccessTokenCache(platcode As String, CursetHandler As SetAccessTokenHandler, CurgetHandler As GetAccessTokenHandler)
        SyncLock lockObj
            DicM_setHandler(platcode) = CursetHandler
            DicM_getHandler(platcode) = CurgetHandler
        End SyncLock
    End Sub

    Public Shared Function GetAccessToken(platcode As String) As String
        If Not DicM_setHandler.ContainsKey(platcode) OrElse Not DicM_getHandler.ContainsKey(platcode) Then
            Throw New ArgumentNullException(platcode + "的setHandler,getHandler没有赋值", "请先调用ConfigAccessTokenCache")
        End If
        If Not DicAppID.ContainsKey(platcode) OrElse Not DicAppSecret.ContainsKey(platcode) Then
            Throw New ArgumentNullException(platcode + "的AppID,AppSecret没有赋值", "请先调用ConfigGlobalCredential")
        End If
        Dim result As String
        SyncLock lockObj
            Dim at As String = DicM_getHandler(platcode)()
            If String.IsNullOrEmpty(at) Then
                Dim credential As ClientCredential = ClientCredential.GetCredential(DicAppID(platcode), DicAppSecret(platcode))
                DicM_setHandler(platcode)(credential)
                at = credential.access_token
            End If
            result = at
        End SyncLock
        Return result
    End Function
    '检验signature
    Public Shared Function CheckSignature(signature As String, timestamp As String, nonce As String, token As String) As Boolean
        Dim result As Boolean
        If String.IsNullOrEmpty(signature) Then
            result = False
        Else
            Dim tmpList As List(Of String) = New List(Of String)(3)
            tmpList.Add(token)
            tmpList.Add(timestamp)
            tmpList.Add(nonce)
            tmpList.Sort()
            Dim tmpStr As String = String.Join("", tmpList.ToArray())
            Dim strResult As String = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1")
            result = signature.Equals(strResult, StringComparison.InvariantCultureIgnoreCase)
        End If
        Return result
    End Function
    '处理用户消息和事件
    Public Shared Function ReplyMsgProcess(platcode As String) As ReplyBaseMsg
        Dim inputStream As Stream = HttpContext.Current.Request.InputStream
        Dim pos As Long = inputStream.Position
        inputStream.Position = 0L
        Dim buffer(inputStream.Length - 1) As Byte
        inputStream.Read(buffer, 0, buffer.Length)
        inputStream.Position = pos
        Dim xml As String = Encoding.UTF8.GetString(buffer)
        Dim dict As Dictionary(Of String, String) = Util.GetDictFromXml(xml)
        '抛出事件，便于日志记录
        RaiseEvent OnReceivePlatMsgEvent(platcode, xml, dict)
        Dim key As String = String.Empty
        Dim replyMsg As ReplyBaseMsg = ReplyEmptyMsg.Instance
        If dict.ContainsKey("Event") Then
            Dim evt As String = dict("Event").ToLower()
            key = "event_"
            Dim text As String = evt
            Select Case text
                Case "click"
                    Dim msg As EventClickMsg = New EventClickMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.Click, .EventKey = dict("EventKey")}
                    replyMsg = GetReply(Of EventClickMsg)(key + MyEventType.Click.ToString(), platcode, msg)
                Case "location"
                    Dim msg3 As EventLocationMsg = New EventLocationMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.Location, .Latitude = Double.Parse(dict("Latitude")), .Longitude = Double.Parse(dict("Longitude")), .Precision = Double.Parse(dict("Precision"))}
                    replyMsg = GetReply(Of EventLocationMsg)(key + MyEventType.Location.ToString(), platcode, msg3)
                Case "scan"
                    Dim msg4 As EventFansScanMsg = New EventFansScanMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.FansScan, .EventKey = dict("EventKey"), .Ticket = dict("Ticket")}
                    replyMsg = GetReply(Of EventFansScanMsg)(key + MyEventType.FansScan.ToString(), platcode, msg4)
                Case "unsubscribe"
                    Dim msg5 As EventUnattendMsg = New EventUnattendMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.Unattend}
                    replyMsg = GetReply(Of EventUnattendMsg)(key + MyEventType.Unattend.ToString(), platcode, msg5)
                Case "subscribe"
                    If dict.ContainsKey("Ticket") Then
                        Dim msg6 As EventUserScanMsg = New EventUserScanMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.UserScan, .Ticket = dict("Ticket"), .EventKey = dict("EventKey")}
                        replyMsg = GetReply(Of EventUserScanMsg)(key + MyEventType.UserScan.ToString(), platcode, msg6)
                    Else
                        Dim msg7 As EventAttendMsg = New EventAttendMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MyEventType = MyEventType.Attend}
                        replyMsg = GetReply(Of EventAttendMsg)(key + MyEventType.Attend.ToString(), platcode, msg7)
                    End If
            End Select
        Else
            If dict.ContainsKey("MsgId") Then
                Dim msgType As String = dict("MsgType")
                key = msgType
                Dim text As String = msgType
                Select Case text
                    Case "text"
                        Dim msg15 As RecTextMsg = New RecTextMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MsgId = Long.Parse(dict("MsgId")), .Content = dict("Content")}
                        replyMsg = GetReply(Of RecTextMsg)(key, platcode, msg15)
                    Case "image"
                        Dim msg14 As RecImageMsg = New RecImageMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MsgId = Long.Parse(dict("MsgId")), .PicUrl = dict("PicUrl"), .MediaId = dict("MediaId")}
                        replyMsg = GetReply(Of RecImageMsg)(key, platcode, msg14)
                    Case "voice"
                        Dim msg13 As RecVoiceMsg = New RecVoiceMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MsgId = Long.Parse(dict("MsgId")), .mimeType = dict("mimeType"), .name = dict("name"), .Url = dict("Url")}
                        replyMsg = GetReply(Of RecVoiceMsg)(key, platcode, msg13)
                    Case "video"
                        Dim msg12 As RecVideoMsg = New RecVideoMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MsgId = Long.Parse(dict("MsgId")), .name = dict("name"), .url = dict("url"), .mimeType = dict("mimeType")}
                        replyMsg = GetReply(Of RecVideoMsg)(key, platcode, msg12)
                    Case "location"
                        Dim msg11 As RecLocationMsg = New RecLocationMsg() With {.CreateTime = Long.Parse(dict("CreateTime")), .FromUserName = dict("FromUserName"), .ToUserName = dict("ToUserName"), .MsgId = Long.Parse(dict("MsgId")), .Label = dict("Label"), .Location_X = Double.Parse(dict("Location_X")), .Location_Y = Double.Parse(dict("Location_Y")), .Scale = Integer.Parse(dict("Scale"))}
                        replyMsg = GetReply(Of RecLocationMsg)(key, platcode, msg11)
                End Select
            End If
        End If
        Return replyMsg
    End Function


    '注册消息处理程序
    Public Shared Sub RegisterMsgHandler(Of TMsg As RecBaseMsg)(handler As MyFunc(Of TMsg, String, ReplyBaseMsg))
        Dim type As Type = GetType(TMsg)
        Dim key As String = String.Empty
        If type Is GetType(RecTextMsg) Then
            key = "text"
        ElseIf type Is GetType(RecImageMsg) Then
            key = "image"
        ElseIf type Is GetType(RecLocationMsg) Then
            key = "location"
        ElseIf type Is GetType(RecVideoMsg) Then
            key = "video"
        ElseIf type Is GetType(RecVoiceMsg) Then
            key = "voice"
        Else
            Return
        End If
        m_msgHandlers(key.ToLower()) = handler
    End Sub


    '注册事件处理程序
    Public Shared Sub RegisterEventHandler(Of TEvent As EventBaseMsg)(handler As MyFunc(Of TEvent, String, ReplyBaseMsg))
        Dim type As Type = GetType(TEvent)
        Dim key As String = "event_"
        If type Is GetType(EventClickMsg) Then
            key += MyEventType.Click.ToString()
        ElseIf type Is GetType(EventFansScanMsg) Then
            key += MyEventType.FansScan.ToString()
        ElseIf type Is GetType(EventAttendMsg) Then
            key += MyEventType.Attend.ToString()
        ElseIf type Is GetType(EventLocationMsg) Then
            key += MyEventType.Location.ToString()
        ElseIf type Is GetType(EventUnattendMsg) Then
            key += MyEventType.Unattend.ToString()
        ElseIf type Is GetType(EventUserScanMsg) Then
            key += MyEventType.UserScan.ToString()
        Else
            Return
        End If
        m_msgHandlers(key.ToLower()) = handler
    End Sub


    '多平台模式处理
    Private Shared Function GetReply(Of TMsg As BaseRecMsg)(key As String, platcode As String, msg As TMsg) As ReplyBaseMsg
        key = key.ToLower()
        Dim result As ReplyBaseMsg
        If m_msgHandlers.ContainsKey(key) Then
            Dim handler As MyFunc(Of TMsg, String, ReplyBaseMsg) = TryCast(m_msgHandlers(key), MyFunc(Of TMsg, String, ReplyBaseMsg))
            Dim replyMsg As ReplyBaseMsg = handler(msg, platcode)
            If replyMsg.CreateTime = 0L Then
                replyMsg.CreateTime = DateTime.Now.Ticks
            End If
            If String.IsNullOrEmpty(replyMsg.FromUserName) Then
                replyMsg.FromUserName = msg.ToUserName
            End If
            If String.IsNullOrEmpty(replyMsg.ToUserName) Then
                replyMsg.ToUserName = msg.FromUserName
            End If
            result = replyMsg
        Else
            result = ReplyEmptyMsg.Instance
        End If
        Return result
    End Function

   


    '主动给用户发消息（用户）
    Public Shared Function SendMsg(platcode As String, msg As SendBaseMsg) As ReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/message/custom/send?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim json As String = msg.GetJSON()
        Dim retJson As String = Util.HttpPost2(url, json)
        Return Util.JsonTo(Of ReturnCode)(retJson)
    End Function

    '按照分组群发
    Public Shared Function SendMessByGroup(platcode As String, mess As MessBaseMess) As SendReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/message/group/send?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim json As String = Util.ToJson(mess)
        Dim retJson As String = Util.HttpPost2(url, json)
        Return Util.JsonTo(Of SendReturnCode)(retJson)
    End Function


    '自定义菜单
    Public Shared Function CreateMenu(platcode As String, menu As CustomMenu) As ReturnCode
        If Not DicAppID.ContainsKey(platcode) OrElse Not DicAppSecret.ContainsKey(platcode) Then
            Throw New ArgumentNullException(platcode + "的AppID,AppSecret没有赋值", "请先调用ConfigGlobalCredential")
        End If
        Dim json As String = menu.GetJSON()
        Return CreateMenu(json, platcode)
    End Function
    Public Shared Function CreateMenu(platcode As String, menuJSON As String) As ReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/menu/create?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim retJson As String = Util.HttpPost2(url, menuJSON)
        Return Util.JsonTo(Of ReturnCode)(retJson)
    End Function
    '获取菜单
    Public Shared Function GetMenu(platcode As String) As String
        Dim url As String = "https://api.yixin.im/cgi-bin/menu/get?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Return Util.HttpGet2(url)
    End Function
    '删除菜单
    Public Shared Function DeleteMenu(platcode As String) As ReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/menu/delete?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim json As String = Util.HttpGet2(url)
        Return Util.JsonTo(Of ReturnCode)(json)
    End Function

    '生成推广二维码
    Public Shared Function CreateQRCode(isTemp As Boolean, scene_id As Integer, platcode As String) As QRCodeTicket
        Dim url As String = "https://api.yixin.im/cgi-bin/qrcode/create?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim arg_25_0 As String = If(isTemp, "QR_SCENE", "QR_LIMIT_SCENE")
        Dim data As String
        If isTemp Then
            data = "{""expire_seconds"": 1800, ""action_name"": ""QR_SCENE"", ""action_info"": {""scene"": {""scene_id"":" + scene_id + "}}}"
        Else
            data = "{""action_name"": ""QR_LIMIT_SCENE"", ""action_info"": {""scene"": {""scene_id"": " + scene_id + "}}}"
        End If
        Dim json As String = Util.HttpPost2(url, data)
        Dim result As QRCodeTicket
        If json.IndexOf("ticket") > 0 Then
            result = Util.JsonTo(Of QRCodeTicket)(json)
        Else
            result = New QRCodeTicket() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        End If
        Return result
    End Function
    '通过ticket换取二维码
    Public Shared Function GetQRUrl(qrcodeTicket As String) As String
        Return " https://api.yixin.im/cgi-bin/qrcode/showqrcode?ticket=" + HttpUtility.HtmlEncode(qrcodeTicket)
    End Function

    '获取关注用户列表
    Public Shared Function GetFollowers(next_openid As String, platcode As String) As Followers
        Dim url As String = "https://api.yixin.im/cgi-bin/user/get?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        If Not String.IsNullOrEmpty(next_openid) Then
            url = url + "&next_openid=" + next_openid
        End If
        Dim json As String = Util.HttpGet2(url)
        Dim result As Followers
        If json.IndexOf("errcode") > 0 Then
            result = New Followers() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            result = Util.JsonTo(Of Followers)(json)
        End If
        Return result
    End Function
    '获取全部关注者列表
    Public Shared Function GetAllFollowers(platcode As String) As Followers
        Dim allFollower As Followers = New Followers()
        allFollower.data = New Followers.Curdata()
        allFollower.data.openid = New List(Of String)()
        Dim next_openid As String = String.Empty
        Do
            Dim f = GetFollowers(next_openid, platcode)
            If f.[error] IsNot Nothing Then
                allFollower.error = f.error
                Exit Do
            Else
                If f.count > 0 Then
                    For Each opid As String In f.data.openid
                        allFollower.data.openid.Add(opid)
                    Next
                    If f.next_openid = allFollower.data.openid(f.count - 1) Then
                        allFollower.total = f.total
                        Exit Do
                    Else
                        allFollower.total += f.count
                    End If
                End If
                next_openid = f.next_openid
            End If
        Loop While (String.IsNullOrEmpty(next_openid) = False)
        allFollower.count = allFollower.total
        Return allFollower
    End Function

    '获取用户基本信息
    Public Shared Function GetUserInfo(openid As String, lang As LangType, platcode As String) As UserInfo
        Dim url As String = "https://api.yixin.im/cgi-bin/user/info?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url = url + access_token + "&openid=" + openid + "&lang=" + lang.ToString()
        Dim json As String = Util.HttpGet2(url)
        Dim result As UserInfo
        If json.IndexOf("errcode") > 0 Then
            result = New UserInfo() With {.openid = openid, .[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            result = Util.JsonTo(Of UserInfo)(json)
        End If
        Return result
    End Function

    '创建分组
    Public Shared Function CreateGroup(name As String, platcode As String) As GroupInfo
        Dim url As String = "https://api.yixin.im/cgi-bin/groups/create?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim post As String = "{""group"":{""name"":""" + name + """}}"
        Dim json As String = Util.HttpPost2(url, post)
        Dim result As GroupInfo
        If json.IndexOf("errcode") > 0 Then
            result = New GroupInfo() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            Dim dict As Dictionary(Of String, Dictionary(Of String, Object)) = Util.JsonTo(Of Dictionary(Of String, Dictionary(Of String, Object)))(json)
            Dim gi As GroupInfo = New GroupInfo()
            Dim gpdict As Dictionary(Of String, Object) = dict("group")
            gi.id = Convert.ToInt32(gpdict("id"))
            gi.name = gpdict("name").ToString()
            result = gi
        End If
        Return result
    End Function
    '查询所有分组
    Public Shared Function GetGroups(platcode As String) As Groups
        Dim url As String = "https://api.yixin.im/cgi-bin/groups/get?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim json As String = Util.HttpGet2(url)
        Dim result As Groups
        If json.IndexOf("errcode") > 0 Then
            Dim gs As Groups = New Groups()
            gs.[error] = Util.JsonTo(Of ReturnCode)(json)
            result = gs
        Else
            Dim dict As Dictionary(Of String, List(Of Dictionary(Of String, Object))) = Util.JsonTo(Of Dictionary(Of String, List(Of Dictionary(Of String, Object))))(json)
            Dim gs As Groups = New Groups()
            Dim gilist As List(Of Dictionary(Of String, Object)) = dict("groups")
            For Each gidict As Dictionary(Of String, Object) In gilist
                gs.Add(New GroupInfo() With {.name = gidict("name").ToString(), .id = Convert.ToInt32(gidict("id")), .count = Convert.ToInt32(gidict("count"))})
            Next
            result = gs
        End If
        Return result
    End Function
    '查询用户所在分组
    Public Shared Function GetUserGroup(openid As String, platcode As String) As GroupID
        Dim url As String = "https://api.yixin.im/cgi-bin/groups/getid?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim post As String = "{""openid"":""" + openid + """}"
        Dim json As String = Util.HttpPost2(url, post)
        Dim result As GroupID
        If json.IndexOf("errcode") > 0 Then
            result = New GroupID() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            Dim dict As Dictionary(Of String, Integer) = Util.JsonTo(Of Dictionary(Of String, Integer))(json)
            result = New GroupID() With {.id = dict("groupid")}
        End If
        Return result
    End Function
    '修改分组名
    Public Shared Function UpdateGroup(id As Integer, name As String, platcode As String) As ReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/groups/update?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url += access_token
        Dim post As String = "{'group':{'id':" + id + ",'name':'" + name + "'}}"
        Dim json As String = Util.HttpPost2(url, post)
        Return Util.JsonTo(Of ReturnCode)(json)
    End Function
    '移动用户分组
    Public Shared Function MoveGroup(ByVal openid As String, ByVal groupid As Integer, ByVal platcode As String) As ReturnCode
        Dim url As String = "https://api.yixin.im/cgi-bin/groups/members/update?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url = url + access_token
        Dim post = "{'openid':" + openid + ",'to_groupid':'" + groupid + "'}"
        Dim json = Util.HttpPost2(url, post)
        Return Util.JsonTo(Of ReturnCode)(json)
    End Function


    '上传多媒体文件
    Public Shared Function UploadMedia(file As String, type As String, platcode As String) As MediaInfo
        Dim url As String = "https://api.yixin.im/cgi-bin/media/upload?access_token="
        Dim access_token As String = GetAccessToken(platcode)
        url = url + access_token + "&type=" + type.ToString()
        Dim json As String = Util.HttpUpload(url, file)
        Dim result As MediaInfo
        If json.IndexOf("errcode") > 0 Then
            result = New MediaInfo() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            result = Util.JsonTo(Of MediaInfo)(json)
        End If
        Return result
    End Function

    '获取网页授权
    Public Shared Function BuildWebCodeUrl(appid As String, redirect As String, scope As String, Optional state As String = "") As String
        Return String.Format(" http://open.plus.yixin.im/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}#wechat_redirect", appid, redirect, scope, state)
    End Function
    Public Shared Function MBuildWebCodeUrl(platcode As String, redirect As String, scope As String, Optional state As String = "") As String
        If Not DicAppID.ContainsKey(platcode) OrElse Not DicAppSecret.ContainsKey(platcode) Then
            Throw New ArgumentNullException(platcode + "的AppID,AppSecret没有赋值", "请先调用ConfigGlobalCredential")
        End If
        Return BuildWebCodeUrl(DicAppID(platcode), redirect, scope, state)
    End Function
    Public Shared Function GetWebAccessToken(appId As String, appSecret As String, code As String) As WebCredential
        Return WebCredential.GetCredential(appId, appSecret, code)
    End Function
    Public Shared Function GetWebAccessToken(platcode As String, code As String) As WebCredential
        If Not DicAppID.ContainsKey(platcode) OrElse Not DicAppSecret.ContainsKey(platcode) Then
            Throw New ArgumentNullException(platcode + "的AppID,AppSecret没有赋值", "请先调用ConfigGlobalCredential")
        End If
        Return WebCredential.GetCredential(DicAppID(platcode), DicAppSecret(platcode), code)
    End Function
    Public Shared Function MGetWebAccessToken(platcode As String, code As String) As WebCredential
        Return GetWebAccessToken(platcode, code)
    End Function
    Public Shared Function GetWebUserInfo(access_token As String, openid As String, lang As LangType) As WebUserInfo
        Dim url As String = String.Format("https://api.yixin.im/sns/userinfo?access_token={0}&openid={1}&lang={2}", access_token, openid, lang.ToString())
        Dim json As String = Util.HttpGet2(url)
        Dim result As WebUserInfo
        If json.IndexOf("errcode") > 0 Then
            result = New WebUserInfo() With {.[error] = Util.JsonTo(Of ReturnCode)(json)}
        Else
            result = Util.JsonTo(Of WebUserInfo)(json)
        End If
        Return result
    End Function

   

End Class
